package com.ly.heart.service.impl;

import java.util.List;
import java.util.Optional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.PageParam;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.ActTaskCommentEntity;
import com.ly.heart.domain.KingProfitLossDetailEntity;
import com.ly.heart.domain.dto.KingProfitLossDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.heart.domain.vo.KingProfitLossVo;
import com.ly.heart.mapper.KingProfitLossMapper;
import com.ly.heart.service.IActModelService;
import com.ly.heart.service.IActTaskCommentService;
import com.ly.heart.service.IKingProfitLossDetailService;
import com.ly.heart.service.IKingProfitLossService;
import com.ly.heart.util.ChineseToPinyin;
import org.springframework.stereotype.Service;
import com.ly.heart.domain.KingProfitLossEntity;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 盘盈单/盘亏单基础信息Service业务层处理
 *
 * @author wutao
 * @date 2024-07-23
 */
@Service
public class KingProfitLossServiceImpl extends ServiceImpl<KingProfitLossMapper, KingProfitLossEntity> implements IKingProfitLossService {

    @Resource
    private KingProfitLossMapper kingProfitLossEntityMapper;
    @Resource
    private IKingProfitLossDetailService iKingProfitLossDetailService;
    @Resource
    private IActModelService iActModelService;
    @Resource
    private IActTaskCommentService iActTaskCommentService;

    /**
     * 查询盘盈单/盘亏单基础信息
     *
     * @param id 盘盈单/盘亏单基础信息ID
     * @return 盘盈单/盘亏单基础信息
     */
    @Override
    public KingProfitLossVo selectKingProfitLossEntityById ( String id ) {
        KingProfitLossVo vo = new KingProfitLossVo ();
        // 基本
        KingProfitLossEntity profitLossEntity = kingProfitLossEntityMapper.selectKingProfitLossEntityById ( id );
        vo.setKingProfitLossEntity ( profitLossEntity );
        // 明细
        List<KingProfitLossDetailEntity> list = iKingProfitLossDetailService.list ( new LambdaQueryWrapper<KingProfitLossDetailEntity> ().
                eq ( KingProfitLossDetailEntity :: getRelationId, id ) );
        vo.setKingProfitLossDetailEntities ( list );
        return vo;
    }

    /**
     * 查询盘盈单/盘亏单基础信息列表
     *
     * @param kingProfitLossEntity 盘盈单/盘亏单基础信息
     * @return 盘盈单/盘亏单基础信息
     */
    @Override
    public AjaxResult selectKingProfitLossEntityList ( KingProfitLossEntity kingProfitLossEntity ) {
        kingProfitLossEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingProfitLossEntity.setPage ( ( kingProfitLossEntity.getPage () - 1 ) * kingProfitLossEntity.getLimit () );
        List<KingProfitLossEntity> kingProfitLossEntities = kingProfitLossEntityMapper.selectKingProfitLossEntityList ( kingProfitLossEntity );
        kingProfitLossEntities.forEach ( profit -> {
            //处理最后一个审批人
            ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( profit.getInstanceId () );
            if ( actTaskCommentEntity != null ) {
                profit.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                profit.setApprovedRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
            ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( profit.getInstanceId () );
            Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
                profit.setCurrentTask ( currentTask );
            } );
        } );
        PageParam p = new PageParam ();
        p.setTotal ( kingProfitLossEntityMapper.queryCount ( kingProfitLossEntity ) ).setRecords ( kingProfitLossEntities ).setCurrent ( kingProfitLossEntity.getPage () );
        return AjaxResult.success ( p );
    }

    @Override
    public AjaxResult submit ( KingProfitLossEntity kingProfitLossEntity ) {
        if ( StringUtils.isBlank ( kingProfitLossEntity.getId () ) ) {
            return AjaxResult.error ( "无此盈亏单" );
        }
        KingProfitLossEntity profitLossEntity = this.getById ( kingProfitLossEntity );
        String bizName = profitLossEntity.getType ().intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "盘盈单" : "盘亏单";
        StartProcessDto startDto = new StartProcessDto ().
                setBusinessId ( kingProfitLossEntity.getId () ).
                setBusinessType ( kingProfitLossEntity.getBusinessType () ).setModelId ( kingProfitLossEntity.getModelId () ).
                setBusinessName ( bizName.concat ( kingProfitLossEntity.getId () ) );
        String instanceId = iActModelService.startProcess ( startDto );
        boolean update = this.update ( new LambdaUpdateWrapper<KingProfitLossEntity> ().
                set ( KingProfitLossEntity :: getInstanceId, instanceId ).
                set ( KingProfitLossEntity :: getUpdateDate, DateUtils.getNowDate () ).
                set ( KingProfitLossEntity :: getUpdateUserId, SecurityUtils.getLoginUser ().getUser ().getUserId () ).
                eq ( KingProfitLossEntity :: getId, kingProfitLossEntity.getId () ) );
        if ( ! update ) {
            throw new CustomException ( "提交盈亏单失败！" );
        }
        return AjaxResult.success ( "提交盈亏单成功" );
    }

    /**
     * 新增盘盈单/盘亏单基础信息
     *
     * @param kingProfitLossDto 盘盈单/盘亏单基础信息
     * @return 结果
     */
    @Override
    @Transactional ( rollbackFor = Exception.class, propagation = Propagation.REQUIRED )
    public AjaxResult draft ( KingProfitLossDto kingProfitLossDto ) {
        KingProfitLossEntity kingProfitLossEntity = kingProfitLossDto.getKingProfitLossEntity ();
        Integer type = kingProfitLossEntity.getType ();
        if ( type == null ) {
            throw new CustomException ( "业务类型type【" + type + "】未确定" );
        }
        kingProfitLossEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        kingProfitLossEntity.setCreateUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingProfitLossEntity.setCreateDate ( DateUtils.getNowDate () );
        String firstLetter = ChineseToPinyin.getFirstLetter ( type.intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "盘盈单" : "盘亏单" );
        int count = this.count ( new QueryWrapper<KingProfitLossEntity> ().eq ( "type", type.intValue () ) );
        String code = String.format ( "%08d", count );
        kingProfitLossEntity.setDocNo ( firstLetter.concat ( code ) );
        updateDetail ( kingProfitLossDto.getKingProfitLossDetailEntities (), kingProfitLossEntity.getId (), type );
        kingProfitLossEntity.setState ( ConstUtil.STATE_IN_PROCESS );
        boolean save = this.save ( kingProfitLossEntity );
        if ( ! save ) {
            throw new CustomException ( type.intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "新增盘盈单失败" : "新增盘亏单失败" );
        }
        return AjaxResult.success ( type.intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "新增盘盈单成功" : "新增盘亏单成功", kingProfitLossEntity.getId () );
    }

    /**
     * 修改盘盈单/盘亏单基础信息
     *
     * @param kingProfitLossDto 盘盈单/盘亏单基础信息
     * @return 结果
     */
    @Override
    public AjaxResult updateKingProfitLossEntity ( KingProfitLossDto kingProfitLossDto ) {
        KingProfitLossEntity kingProfitLossEntity = kingProfitLossDto.getKingProfitLossEntity ();
        kingProfitLossEntity.setUpdateDate ( DateUtils.getNowDate () );
        kingProfitLossEntity.setUpdateUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        Integer type = kingProfitLossEntity.getType ();
        updateDetail ( kingProfitLossDto.getKingProfitLossDetailEntities (), kingProfitLossEntity.getId (), type );
        boolean b = this.updateById ( kingProfitLossEntity );
        if ( ! b ) {
            throw new CustomException ( type.intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "修改盘盈单失败" : "修改盘亏单失败" );
        }
        return AjaxResult.success ();
    }

    /**
     * 批量删除盘盈单/盘亏单基础信息
     *
     * @param ids 需要删除的盘盈单/盘亏单基础信息ID
     * @return 结果
     */
    @Override
    @Transactional ( rollbackFor = Exception.class, propagation = Propagation.REQUIRED )
    public AjaxResult deleteKingProfitLossEntityByIds ( String[] ids ) {
        LambdaUpdateWrapper<KingProfitLossEntity> profitUpdate = new LambdaUpdateWrapper<> ();
        profitUpdate.set ( KingProfitLossEntity :: getIsUsed, ConstUtil.IS_USED_NO ).in ( KingProfitLossEntity :: getId, ids );
        boolean update = this.update ( profitUpdate );
        if ( ! update ) {
            throw new CustomException ( "删除盘点单失败！" );
        }
        LambdaUpdateWrapper<KingProfitLossDetailEntity> detailUpdate = new LambdaUpdateWrapper<> ();
        detailUpdate.set ( KingProfitLossDetailEntity :: getIsUsed, ConstUtil.IS_USED_NO ).in ( KingProfitLossDetailEntity :: getRelationId, ids );
        boolean updateDetail = iKingProfitLossDetailService.update ( detailUpdate );
        if ( ! updateDetail ) {
            throw new CustomException ( "删除盘点单失败！" );
        }
        return AjaxResult.success ( "删除盘点单成功" );
    }

    /**
     * 删除盘盈单/盘亏单基础信息信息
     *
     * @param id 盘盈单/盘亏单基础信息ID
     * @return 结果
     */
    @Override
    public int deleteKingProfitLossEntityById ( String id ) {
        return kingProfitLossEntityMapper.deleteKingProfitLossEntityById ( id );
    }


    /**
     * 新增盘盈单/盘亏单明细
     *
     * @param kingProfitLossDetailEntities
     */
    private void updateDetail ( List<KingProfitLossDetailEntity> kingProfitLossDetailEntities, String relationId, Integer type ) {
        if ( ! CollectionUtils.isEmpty ( kingProfitLossDetailEntities ) ) {
            iKingProfitLossDetailService.remove ( new LambdaUpdateWrapper<KingProfitLossDetailEntity> ().eq ( KingProfitLossDetailEntity :: getRelationId, relationId ) );
            kingProfitLossDetailEntities.forEach ( detail -> {
                detail.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
                detail.setRelationId ( relationId );
                detail.setCreateUserId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
                detail.setCreateDate ( DateUtils.getNowDate () );
                boolean save = iKingProfitLossDetailService.save ( detail );
                if ( ! save ) {
                    throw new CustomException ( type.intValue () == ConstUtil.INVENTORY_PROFIT_TYPE ? "新增盘盈单明细失败" : "新增盘亏单明细失败" );
                }
            } );
        }
    }


}
